#include<sys/wait.h>
#include<stdio.h>
#include<unistd.h>
#include<sys/types.h>
//首先测试pid_t wait(int *status);
void test1()
{
	pid_t id=fork();//创建一个子进程
	//while(1)
	//{}
	if(id==0)
	{
		printf("我是一个子进程，pid：%d,ppid:%d\n",getpid(),getppid());
	//	sleep(10);
	}
	else
	{
		printf("我是一个父进程，pid:%d,ppid:%d\n",getpid(),getppid());
		sleep(10);
		pid_t rid=wait(NULL);//等待子进程结束并且返回目标子进程的pid
		printf("等待成功，子进程pid：%d\n",rid);
	}
}
//其次测试pid_t waitpid(pid_t pid,int* status, int options);
//其中 status是一个输出型参数
void test2()
{
	
	pid_t id=fork();//创建一个子进程
	//while(1)
	//{}
	if(id==0)
	{
		printf("我是一个子进程，pid：%d,ppid:%d\n",getpid(),getppid());
		sleep(10);
		int b=0;
		//if(b==0)
		//{
		//	exit(10);
		//}
		int *p=NULL;
		*p=1;

	}
	else
	{
		int sta=0;
		printf("我是一个父进程，pid:%d,ppid:%d\n",getpid(),getppid());
		//sleep(10);
		//pid_t rid=wait(NULL);//等待子进程结束并且返回目标子进程的pid
		pid_t rid=waitpid(id,&sta,0);
		printf("等待成功，子进程pid：%d，退出码：%d，退出信号：%d\n",rid,WEXITSTATUS(sta),sta&0x7F);
	
	}
}
//非阻塞调用测试
typedef void (*func)();
#define num 5
func h[num+1];//这是一个函数指针数组
void DownLoad()
{
	printf("这是一个下载任务\n");
}
void UpLoad()
{
	printf("这是一个上传任务\n");
}
void Flush()
{
	printf("这是一个刷新任务\n");
}
void add(func h[],func f)
{
	int i=0;
	//该循环的目的是为了让i指向函数指针插入的位置
	for(;i<num;i++)
	{
		if(h[i]==NULL)
		{
			break;
		}
	}
	if(i==num)
	{
		return;//函数指针数组满了，不能再加入函数指针了
	}
	h[i]=f;
	h[i+1]=NULL;
}

void test3()
{
	add(h,DownLoad);
	add(h,DownLoad);
	add(h,UpLoad);
	add(h,UpLoad);
	add(h,Flush);
	add(h,Flush);
	pid_t id=fork();
	if(id==0)
	{
		int cnt=3;
		while(cnt)
		{
		printf("我是一个子进程，我的pid：%d，ppid：%d\n",getpid(),getppid());
		sleep(8);
		cnt--;
		}
		exit(10);
	}
	else 
	{
		//开始非阻塞调用
		while(1)
		{
			int sta=0;
			int rid=waitpid(id,&sta,WNOHANG);
			if(rid>0)
			{
				printf("等待成功，子进程pid：%d，退出码：%d，退出信号：%d\n",rid,WEXITSTATUS(sta),sta&0x7F);
				break;
			}
			else if(rid==0)
			{
				//非阻塞调用，子进程并未结束
				int i=0;
				for(;i<num;i++)
				{
					h[i]();
				}
				printf("本轮调用结束，子进程没有退出\n");
				sleep(1);
			}
			else
			{
				printf("等待失败\n");
			}
		}
	}

}
int main()
{
	//test1();
	//test2();
	test3();
	return 0;
}
